package util

import (
	"fmt"
	"reflect"
	"strings"
)

// 获取结构体属性值，根据json标签
func GetStructPropValueByJsonTag(v any, jsonTag string) (any, error) {
	val := reflect.ValueOf(v)
	t := reflect.TypeOf(v)
	// 如果传入的是指针，获取指针指向的值
	if val.Kind() == reflect.Ptr {
		val = val.Elem()
	}
	// 判断是否是结构体类型
	if t.Kind() != reflect.Struct {
		return nil, fmt.Errorf("GetStructPropValueByJsonTag: %v is not a struct", val.Type())
	}

	if jsonTag == "" {
		return nil, fmt.Errorf("GetStructPropValueByJsonTag: jsonTag is empty")
	}

	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		fieldJsonTag := field.Tag.Get("json")
		if fieldJsonTag == jsonTag {
			return val.Field(i).Interface(), nil
		}
		// 如果字段是嵌套结构体，递归处理
		if field.Type.Kind() == reflect.Struct {
			res, err := GetStructPropValueByJsonTag(val.Field(i).Interface(), jsonTag)
			if err != nil {
				return nil, err
			}
			if res != nil {
				return res, nil
			}
		}
	}

	return nil, nil
}

// 将结构体转换为 map[string]any，使用 json 标签作为键
// 因为用到了反射，只能处理导出字段，非导出字段不能处理
// isRecursive 为 true 时，将递归处理结构体的字段
func StructToMap(obj interface{}, isRecursive ...bool) map[string]any {
	result := make(map[string]any)
	// 获取传入对象的反射值
	v := reflect.ValueOf(obj)
	// 若传入的是指针，获取指针指向的值
	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}
	// 检查是否为结构体
	if v.Kind() != reflect.Struct {
		return result
	}
	// 是否递归处理嵌套
	isRecursiveNested := false
	if len(isRecursive) > 0 && isRecursive[0] {
		isRecursiveNested = true
	}
	// 获取结构体的类型
	t := v.Type()
	for i := 0; i < v.NumField(); i++ {
		// // 获取字段
		// field := v.Field(i)
		// // 获取字段的 json 标签
		// tag := t.Field(i).Tag.Get("json")
		// if tag == "" {
		// 	// 若 json 标签为空，使用字段名
		// 	tag = t.Field(i).Name
		// } else {
		// 	// 处理 json 标签中的额外选项（如 omitempty）
		// 	parts := strings.Split(tag, ",")
		// 	tag = parts[0]
		// }
		// // 若字段可导出且不为零值，将其添加到结果 map 中
		// if t.Field(i).PkgPath == "" && !field.IsZero() {
		// 	result[tag] = field.Interface()
		// }
		field := v.Field(i)
		structField := t.Field(i)
		// 跳过未导出的字段
		if structField.PkgPath != "" {
			continue
		}
		// 获取JSON标签
		tag := structField.Tag.Get("json")
		if tag == "" {
			tag = structField.Name
		} else {
			parts := strings.Split(tag, ",")
			tag = parts[0]
			// 跳过被忽略的字段
			if tag == "-" {
				continue
			}
			// 检查omitempty选项
			hasOmitEmpty := false
			for _, part := range parts[1:] {
				if part == "omitempty" {
					hasOmitEmpty = true
					break
				}
			}
			// 应用omitempty逻辑
			if hasOmitEmpty && IsEmpty(field.Interface()) {
				continue
			}
		}

		// 判断是否递归处理嵌套结构体和切片等
		if isRecursiveNested {
			if field.Kind() == reflect.Struct {
				result[tag] = StructToMap(field.Interface(), isRecursive...)
			} else if field.Kind() == reflect.Slice || field.Kind() == reflect.Array {
				sliceResult := make([]any, field.Len())
				for j := 0; j < field.Len(); j++ {
					elem := field.Index(j)
					if elem.Kind() == reflect.Struct {
						sliceResult[j] = StructToMap(elem.Interface(), isRecursive...)
					} else {
						sliceResult[j] = elem.Interface()
					}
				}
				result[tag] = sliceResult
			} else if field.Kind() == reflect.Ptr && !field.IsNil() {
				// 处理指针
				elem := field.Elem()
				if elem.Kind() == reflect.Struct {
					result[tag] = StructToMap(elem.Interface(), isRecursive...)
				} else {
					result[tag] = elem.Interface()
				}
			}
			continue
		}
		result[tag] = field.Interface()
	}
	return result
}
